paint-brush
How I Use AI in Frontend Developmentby@snezhkinv
745 reads
745 reads

How I Use AI in Frontend Development

by Vladislav SnezhkinJune 25th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

In this article, I want to tell you what AI tools I use in the development of my Web projects to simplify my work. I will show examples using JavaScript, TypeScript & ReactJS. I'll break this article into 2 parts: a code writing assistant and test writing tools.
featured image - How I Use AI in Frontend Development
Vladislav Snezhkin HackerNoon profile picture

In this article, I want to tell you what AI tools I use in the development of my Web projects to simplify my work and focus on important and complex code sections. I will show examples using JavaScript, TypeScript & ReactJS.


I will break this article into two parts: a code writing assistant and test writing tools.

Code writing assistant

There are various moments when assistance in writing code is needed:


  • Writing Basic Code: For instance, this could be creating an empty component in ReactJS. These are template-like tasks that often require copying from documentation. While finding and copying this code takes time, automated tools can streamline this process.
  • Avoiding Search for Issues: For example, you might encounter an error without knowing how to fix it. Instead of searching for solutions online, automated tools can provide immediate suggestions and fixes.

BlackBox website

To do this, use the Blackbox AI Code tool and install it in our VS Code editor.


Open VSCode. Select extensions in the left panel, write bblack boxin the search bar, and click install.

On the onboarding page, he tells us that he can do five things.


Let's try all the functionality.

BlackBox Code Chat

Create a new file Weather.jsx, let's ask blackbox to write a component that will receive the weather forecast and show us the forecast for today. It is important to activate the checkbox Chat with Your Code Files. Otherwise, it will not understand the context and write code in another programming language. After activating the checkbox, the context of what was written in the file and the programming language we are using must be taken into account.


Blackbox made a number of mistakes:

  • it specified the wrong path to the react library

  • if we try to run our code without specifying the key, we will get an error.

    The error is due to the fact that the request has failed, and the program has nothing to destruct


Ask AI to fix errors and add error handling if the API returns nothing. I write this prompt:

Add error handling if the API returns nothing and we can't do Destructuring assignment the WeatherData object




It works, but the blackbox wrote react with a mistake again!








Now, I'm going to insert the key from openweathermap.

Convert JS to TS

I wrote this prompt. Convert component from javascript to typescript

BlackBox adds an interface for WeatherData, which describes data from the openweathermap API. Also, we use this interface as a generic in our useState data.


import React, { useState, useEffect } from 'react';

interface WeatherData {
  main: {
    temp: number;
    pressure: number;
  };
  weather: {
    description: string;
  }[];
  name: string;
}

const WeatherComponent = () => {
  const [weatherData, setWeatherData] = useState<WeatherData | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const apiKey = 'KEY';
    const city = 'London'; // Replace with your desired city
    const url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKey}`;

    fetch(url)
     .then(response => response.json())
     .then((data: WeatherData) => {
        if (!data ||!data.main ||!data.weather) {
          setError('API returned no data');
        } else {
          setWeatherData(data);
        }
      })
     .catch((error: Error) => setError(error.message));
  }, []);

  if (error) {
    return <div>Error: {error}</div>;
  }

  if (!weatherData) {
    return <div>Loading...</div>;
  }

  try {
    const { main, weather } = weatherData;
    const { temp, pressure } = main;
    const { description } = weather[0];

    return (
      <div>
        <h2>Current Weather in {weatherData.name}</h2>
        <p>Temperature: {temp}°C</p>
        <p>Pressure: {pressure} hPa</p>
        <p>Precipitation: {description}</p>
      </div>
    );
  } catch (error) {
    return <div>Error: Unable to parse weather data</div>;
  }
};

export default WeatherComponent;


Comment code

We have finished developing the weather component, and now we want to leave a comment in our jsdoc-style code. Let's click the "Comment Code" button below in the editor.


You can see how AI commented on our code.

/**
 * A React component that displays the current weather for a given city.
 *
 * @example
 * ```jsx
 * import React from 'eact';
 * import WeatherComponent from './WeatherComponent';
 *
 * const App = () => {
 *   return <WeatherComponent />;
 * };
 * ```
 *
 * @returns {JSX.Element} A JSX element displaying the current weather.
 */
const WeatherComponent = () => {
  /**
   * The weather data fetched from the OpenWeatherMap API.
   *
   * @type {WeatherData | null}
   */
  const [weatherData, setWeatherData] = useState<WeatherData | null>(null);

  /**
   * An error message if the API request fails.
   *
   * @type {string | null}
   */
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    /**
     * The API key for the OpenWeatherMap API.
     *
     * @type {string}
     */
    const apiKey = 'KEY';

    /**
     * The city for which to fetch the weather data.
     *
     * @type {string}
     */
    const city = 'London'; // Replace with your desired city

    /**
     * The URL for the API request.
     *
     * @type {string}
     */
    const url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKey}`;

    fetch(url)
     .then(response => response.json())
     .then((data: WeatherData) => {
        if (!data ||!data.main ||!data.weather) {
          setError('API returned no data');
        } else {
          setWeatherData(data);
        }
      })
     .catch((error: Error) => setError(error.message));
  }, []);

  if (error) {
    return <div>Error: {error}</div>;
  }

  if (!weatherData) {
    return <div>Loading...</div>;
  }

  try {
    /**
     * Destructure the weather data into its components.
     *
     * @type {{ main: { temp: number; pressure: number; }; weather: { description: string; }[]; name: string; }}
     */
    const { main, weather } = weatherData;
    const { temp, pressure } = main;
    const { description } = weather[0];

    return (
      <div>
        <h2>Current Weather in {weatherData.name}</h2>
        <p>Temperature: {temp}°C</p>
        <p>Pressure: {pressure} hPa</p>
        <p>Precipitation: {description}</p>
      </div>
    );
  } catch (error) {
    return <div>Error: Unable to parse weather data</div>;
  }
};

export default WeatherComponent;

/**
 * The shape of the weather data returned by the OpenWeatherMap API.
 *
 * @interface WeatherData
 * @property {object} main - The main weather data.
 * @property {number} main.temp - The temperature in Celsius.
 * @property {number} main.pressure - The atmospheric pressure in hPa.
 * @property {object[]} weather - The weather conditions.
 * @property {string} weather.description - The description of the weather.
 * @property {string} name - The name of the city.
 */
interface WeatherData {
  main: {
    temp: number;
    pressure: number;
  };
  weather: {
    description: string;
  }[];
  name: string;
}



Commit message

Sometimes, the hardest part is coming up with a structured commit message. Sometimes it happens that a lot of files have been touched, let's see how the AI will cope with this.

It created a message that includes: "Removed logo and default React app content, added WeatherComponent".

That's true because I refactored the default React component and imported the WeatherComponent.


Templates

At the beginning of the article, I already said that you often have to create template things. Imagine that Bootstrap is enabled in our project, and we need to quickly build the authorization page template.

My prompt:

Create React component Login page in typescript and also I have bootstrap 4 like css in my project. There are 2 blocks in the center, the one on the left is the authorization form with the fields: login, password, log in. On the right there is a link to create an account


BlackBox suggests installing react-bootstrap. Let's install it npm i react-bootstrap


In App.tsx, import the component and add the onLogin prop.







Yes, it works.


Leetcode algorithm

Now, I would like to ask you to solve a couple of problems with LeetCode.

The task of medium difficulty is to convert a number to the Roman numeral system.

Let's try to convert 1994 to the Roman system, and we will get the correct answer.

[LOG]: "MCMXCIV"

Now, I want to create a React component that looks like an input field. When I enter a number into it and press a button, the result will appear below.

Prompt

Now create a react component for the intToRoman function. The component has an input field that accepts the num argument and a convert button, after clicking on which the conversion result is displayed from below






In addition to the fact that the AI generated the component, it also added validation of the transmitted number.






Test writing

Before that, I used the Unit Test AI as an assistant for writing tests. But you can only have 5 FREE credits every day, but you can buy more. For example, 50 credits cost $4.99. 🤯


But I tried to use BlackBox, and I didn't see any difference in functionality between these products.

Tests for integer to Roman converter

Now I would like to ask you to write tests for our converter.


Okay, run it, and we have a problem. Error-checking tests did not run.


If we run these test cases, we can see what happens.

console.log(intToRoman(0)) → [LOG]: ""

console.log(intToRoman(4000)) → [LOG]: "MMMM"

console.log(intToRoman(-1)) → [LOG]: ""

Let's ask AI to add an exception.

Prompt: Add an exception throw on the argument to the minimum and maximum values


And AI added these rows.

if (num < 1 || num > 3999) {
  throw new Error(`Invalid input: ${num}. Roman numerals only support values between 1 and 3999.`);
}

Next, I will ask to regenerate the failed test.

Prompt: Write jest tests for edge cases for the intToRoman function. A non-negative number by zero and by the maximum number


I am glad that it was able to take the context of the error from the code and use it in our test.

Unfortunately, BlackBox couldn't fix the error for 0 value.

I decided to ask the writing tests unit-test.dev service.

And even this tool gave errors, firstly, it imported the intToTextRoman function, although such a function is not declared anywhere. Secondly, it called the wrong function in the line 61: expect(intToJob(500)).toBe('D');

Test for lodash library

Imagine that you are the developer of a large lodash library, and you have developed the groupBy functions; you want to cover all this with tests without missing the edge cases.

Lodash’s .groupBy() method acts as a handy sorting tool for your data. Lodash **.groupBy() method** creates an object composed of keys generated from the results of running each element of collection through the iterate function. The order of the grouped values is determined by the order they occur in the collection. Also, the corresponding value of each key is an array of elements responsible for generating the key.

groupBy

Let's run it. We got three passes, and one failed the test because we had a typescript error.

Conclusion

I think everyone will draw conclusions for themselves, but my opinion is that AI is a good tool to help, but you need to understand what it suggests to you. I think for developers who are just starting their journey, AI can become a good assistant in writing template code snippets, it can also explain code sections, leave code comments. However, there may be problems with typos in the code or when our application crashes due to the fact that data did not arrive from the server, and it will be difficult for a novice developer here.

As for the tests, you have seen that sometimes AI can be difficult with context; it can import a function that does not exist, write a test, and expect a non-existent value, but it still remains a good helper for inventing all sorts of cases.